package com.fcmeditech.AsianSexyGirls.File;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
//import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;

public class ImageDownloader {
	
	//private Bitmap resultImg;
	public ImageDownloader(){
		//resultImg=null;
	}
	public Bitmap simpleDownloadBitmap(String url){
		final HttpClient hc=new DefaultHttpClient();
		final HttpGet hg=new HttpGet(url);
		try{
    		//connect server get stream
    		HttpResponse hr=hc.execute(hg);
    		final int statusCode = hr.getStatusLine().getStatusCode();
    		if (statusCode != HttpStatus.SC_OK) { 
    	            Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url); 
    	            return null;
    	        }
    		final HttpEntity he=hr.getEntity();
    		if (he != null) {
                InputStream is = null;
                try {
                    is = he.getContent(); 
                    final Bitmap bitmap = BitmapFactory.decodeStream(is);
                    return bitmap;
                } finally {
                    if (is != null) {
                        is.close();  
                    }
                    he.consumeContent();
                }
            }
    		
		}
		catch (Exception e) {
			// Could provide a more explicit error message for IOException or IllegalStateException
	        hg.abort();
	        Log.w("ImageDownloader", "Error while retrieving bitmap from " + url);
		}
		return null;
	}
	///this method changes the decode function to be better
	public Bitmap fineDownloadBitmap(String url){
		final HttpClient hc=new DefaultHttpClient();
		final HttpGet hg=new HttpGet(url);
		try{
    		//connect server get stream
    		HttpResponse hr=hc.execute(hg);
    		final int statusCode = hr.getStatusLine().getStatusCode();
    		if (statusCode != HttpStatus.SC_OK) { 
    	            Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url); 
    	            return null;
    	        }
    		final HttpEntity he=hr.getEntity();
    		if (he != null) {
                InputStream is = null;
                try {
                    is = he.getContent(); 
                    final Bitmap bitmap =BitmapFactory.decodeStream(new FlushedInputStream(is));
                    return bitmap;
                } finally {
                    if (is != null) {
                        is.close();  
                    }
                    he.consumeContent();
                }
            }
    		
		}
		catch (Exception e) {
			// Could provide a more explicit error message for IOException or IllegalStateException
	        hg.abort();
	        Log.w("ImageDownloader", "Error while retrieving bitmap from " + url);
		}
		return null;
	}
	///download image in asynchronic progress and set it into ImageView
	public void download(String url,ImageView iv){
		if (cancelPotentialDownload(url, iv)) {
	         BitmapDownloaderTask task = new BitmapDownloaderTask(iv);
	         DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task);
	         iv.setImageDrawable(downloadedDrawable);
	         task.execute(url);
	     }
	}
	public void download(String url,ImageView iv,Bitmap b){
		if (cancelPotentialDownload(url, iv)) {
	         BitmapDownloaderTask task = new BitmapDownloaderTask(iv,b);
	         DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task);
	         iv.setImageDrawable(downloadedDrawable);
	         task.execute(url);
	     }
	}
	//public Bitmap getCurrentImage(){
	//	return this.resultImg;
	//}
	//////////////////PRIVATE FUNCTION///////////////////////////////////
 	private static boolean cancelPotentialDownload(String url, ImageView iv) {
	    BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(iv);

	    if (bitmapDownloaderTask != null) {
	        String bitmapUrl = bitmapDownloaderTask.url;
	        if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
	            bitmapDownloaderTask.cancel(true);
	        } else {
	            // The same URL is already being downloaded.
	            return false;
	        }
	    }
	    return true;
	}
	
	
	private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView iv) {
	    if (iv != null) {
	        Drawable drawable = iv.getDrawable();
	        if (drawable instanceof DownloadedDrawable) {
	            DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
	            return downloadedDrawable.getBitmapDownloaderTask();
	        }
	    }
	    return null;
	}
	
	/////////////////////////////////////////////////////////////////////
	class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
	    private String url;
	    private final WeakReference<ImageView> ivR;
	    //added;
	    private Bitmap img=null;

	    public BitmapDownloaderTask(ImageView iv) {
	        ivR = new WeakReference<ImageView>(iv);
	    }
	    public BitmapDownloaderTask(ImageView iv,Bitmap _img) {
	        ivR = new WeakReference<ImageView>(iv);
	        img=_img;
	    }
	    @Override
	    // Actual download method, run in the task thread
	    protected Bitmap doInBackground(String... params) {
	         // params comes from the execute() call: params[0] is the url.
	         return fineDownloadBitmap(params[0]);
	    } 

	    @Override
	    // Once the image is downloaded, associates it to the imageView
	    protected void onPostExecute(Bitmap bitmap) {
	        if (isCancelled()) {
	            bitmap = null;
	        }

	        if (ivR != null) {
	            ImageView iv = ivR.get();
	            BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(iv);
	            // Change bitmap only if this process is still associated with it
	            if (this == bitmapDownloaderTask) {
	            	//resultImg=bitmap;//added!
	            	img=bitmap;
	            	
	                iv.setImageBitmap(bitmap);
	            }
	        }
	       /* if (imageViewReference != null) {
	            ImageView imageView = imageViewReference.get();
	            if (imageView != null) {
	                imageView.setImageBitmap(bitmap);
	            }
	        }*/
	    }
	}
	
	static class DownloadedDrawable extends ColorDrawable {
	    private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;

	    public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
	        super(Color.RED);
	        bitmapDownloaderTaskReference =
	            new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
	    }

	    public BitmapDownloaderTask getBitmapDownloaderTask() {
	        return bitmapDownloaderTaskReference.get();
	    }
	}
	
	static class FlushedInputStream extends FilterInputStream {
	    public FlushedInputStream(InputStream inputStream) {
	        super(inputStream);
	    }

	    @Override
	    public long skip(long n) throws IOException {
	        long totalBytesSkipped = 0L;
	        while (totalBytesSkipped < n) {
	            long bytesSkipped = in.skip(n - totalBytesSkipped);
	            if (bytesSkipped == 0L) {
	                  int bytetemp = read();
	                  if (bytetemp < 0) {
	                      break;  // we reached EOF
	                  } else {
	                      bytesSkipped = 1; // we read one byte
	                  }
	           }
	            totalBytesSkipped += bytesSkipped;
	        }
	        return totalBytesSkipped;
	    }
	}
}
